
#include "ITextBlock.h"

using namespace BWE;

ITextBlock::ITextBlock()
{
	dirty = true;
	line = -1;
	width = 0;
	rowHeight = 0;
}
ITextBlock::ITextBlock(const ITextBlock& other)
{
	dirty = other.dirty;
	line = other.line;
	rowHeight = other.rowHeight;
	font = other.font;
	rect = other.rect;
	cells = other.cells;
}
ITextBlock::~ITextBlock()
{

}

void ITextBlock::reset(const BString& text)
{
	this->text = text;
	cells.reset();
	for (auto it = text.begin(); it < text.end(); it++)
	{
		BCode code = it.value();
		cells.append(CodeCell());
		CodeCell& cell = cells.last();
		cell.code = code;
		cell.fresh(font, rowHeight);
	}
	dirty = true;
}
void ITextBlock::append(const BString& text)
{
	for (auto it = text.begin(); it < text.end(); it++)
	{
		BCode code = it.value();

		cells.append(CodeCell());
		CodeCell& cell = cells.last();
		cell.code = code;
		cell.fresh(font, rowHeight);
	}
	dirty = true;
}
bool ITextBlock::insert(int pos, BCode code)
{
	if (cells.insert(pos, CodeCell()))
	{
		CodeCell& cell = cells[pos];
		cell.code = code;
		cell.fresh(font, rowHeight);
		dirty = true;
		return true;
	}
	return false;
}
bool ITextBlock::insert(int pos, const BString& text)
{
	int count = text.count();
	if (!cells.insert(pos, CodeCell(), count))
		return false;
	for (auto it = text.begin(); it.valid(); it++)
	{
		CodeCell& cell = cells[it.index()];
		cell.code = *it;
		cell.fresh(font, rowHeight);
	}
	dirty = true;
	return true;
}

void ITextBlock::refresh(BFont* font)
{
	this->font = font;
	if (font && rowHeight < 1)
		rowHeight = font->height();
	for (int i = 0; i < cells.size(); i++)
	{
		CodeCell& cell = cells[i];
		cell.fresh(font, rowHeight);
	}
	dirty = true;
}
int ITextBlock::wordWidth(int index) const
{
	bool isHead = index == 0;
	if (index > 0)
	{
		isHead = cells[index - 1].isSpace() && !cells[index].isSpace();
	}
	int width = cells[index].rect.width();
	if (isHead)
	{
		while (++index < cells.size())
		{
			if (cells[index].isSpace())
				break;
			width += cells[index].rect.width();
		}
	}
	return width;
}

void ITextBlock::adjust()
{
	if (font)
	{
		if (rowHeight < 1)
			rowHeight = font->height();

		int fontWidth = font->width();
		int fontHeight = font->height();
		int up = fontHeight * 0.2;
		int x = 0;
		int y = 0;
		for (int i = 0; i < cells.size(); i++)
		{
			CodeCell& cell = cells[i];
			int ww = wordWidth(i);
			if (x + ww > width)
			{
				x = 0;
				y += rowHeight;
			}
			cell.rect.setPos(x, y);
			cell.image_rect.setPos(x + cell.image_left, cell.rect.bottom() - cell.image_top - up);
			x += cell.rect.width();
		}

		rect.setSize(width, y + rowHeight);
		dirty = false;
	}
}

int ITextBlock::tail() const
{
	if (cells.empty())
		return 0;
	if (cells.last().code == '\n')
		return cells.size() - 1;
	return cells.size();
}
